package com.keter.framework.persist.config;

import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.CaseInsensitiveContainerFactory;
import com.jfinal.plugin.activerecord.dialect.MysqlDialect;
import com.jfinal.plugin.druid.DruidPlugin;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import java.sql.Connection;

public abstract class BaseDataSource {
    @Value("${db.url}")
    protected String dbUrl;
    @Value("${db.username:any}")
    protected String username;
    @Value("${db.password:any}")
    protected String password;
    @Value("${db.removeAbandoned:false}")
    protected boolean removeAbandoned;
    @Value("${db.removeAbandonedTimeout:300000}")
    protected int removeAbandonedTimeout;

    /* use SPEL expressions */
    @Value("${db.initialSize:2}")
    protected int initialSize;
    @Value("${db.minIdle:1}")
    protected int minIdle;//最小连接池数量
    @Value("${db.maxActive:5}")
    protected int maxActive;
    protected DruidPlugin druid;
    /**
     * 如果不返回DataSource对象
     * spring在执行scheme.sql和data.sql的内容时
     * 会自动调用hsql驱动向默认的hsql数据源（内存）初始化数据库。
     *
     * @return
     * @author gulixing@msn.com
     * @date 2017年1月8日
     */
    @Autowired
    public void initDB() {
        System.out.println("初始化数据源....");
        druid = new DruidPlugin(dbUrl, username, password);
        druid.setInitialSize(initialSize);
        druid.setMinIdle(minIdle);
        druid.setMaxActive(maxActive);
        druid.setRemoveAbandoned(removeAbandoned);
        druid.setRemoveAbandonedTimeoutMillis(removeAbandonedTimeout);
        druid.start();
        System.out.println("数据源初始化完成！");
        System.out.println("初始化 Active Record....");
        initActiveRecordPlugin(dbUrl, druid).start();
        System.out.println("Active Record 初始化完成！");
    }

    protected ActiveRecordPlugin initActiveRecordPlugin(String dsName, String dbUrl, DruidPlugin druid) {
        ActiveRecordPlugin arp = new ActiveRecordPlugin(dsName, druid);
        if (dbUrl.contains("mysql")) {
            arp.setDialect(new MysqlDialect());
        }
        if (dbUrl.contains("sqlite")) {
            arp.setTransactionLevel(Connection.TRANSACTION_READ_UNCOMMITTED); //TRANSACTION_READ_UNCOMMITTED
        }
        arp.setContainerFactory(new CaseInsensitiveContainerFactory(true));
        addMappings(arp);
        return arp;
    }

    protected ActiveRecordPlugin initActiveRecordPlugin(String dbUrl, DruidPlugin druid) {
        String dsName = RandomStringUtils.randomAlphabetic(10);
        return initActiveRecordPlugin(dsName, dbUrl, druid);
    }

    protected abstract void addMappings(ActiveRecordPlugin arp);
}